package router

import (
	"github.com/didip/tollbooth"
	"github.com/didip/tollbooth/limiter"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	"html/template"
	"io"
	"os"
	"sofuny/config"
	"sofuny/controls"
	middle "sofuny/middleware"
	"time"
)

var appConfig = config.App()


// 模板
type Template struct{ templates *template.Template }

func (t *Template) Render(w io.Writer, name string, data interface{}, ctx echo.Context) error {
	return t.templates.ExecuteTemplate(w, name, data)
}

// 初始化
func Start(Addr string) {
	// Echo instance
	app := echo.New()
	// 取消 echo banner
	app.HideBanner = true

	// 静态文件
	app.Static("/static", "./static")

	// 模板
	temp := &Template{ templates: template.Must(template.ParseGlob("templates/*.html")) }
	app.Renderer = temp

	// pre
	app.Pre(middleware.AddTrailingSlash())

	// Middleware
	//app.Use(middleware.Logger())    // logging
	// 自定义日志　输出
	logFile, _ := os.Create("./logs/app_echo.log")
	app.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
		Skipper: middleware.DefaultSkipper,
		Format: `{"remote_ip":"${remote_ip}","time":"${time_rfc3339}","method":"${method}","uri":"${uri}","status":"${status}","error":"${error}","referer":"${referer}","latency_human":"${latency_human}","bytes_in":"${bytes_in}","bytes_out":"${bytes_out}"}` + "\n",
		Output: logFile,
	}))

	app.Use(middleware.Recover())   // recover
	app.Use(middleware.Gzip())      // gzip
	app.Use(middleware.RequestID()) // request id
	app.Use(middleware.Secure())    // 安全
	app.Use(middleware.CORS())      // cors
	//app.Use(middleware.CSRF()) // csrf

	// 自定义中间件
	// referer
	//app.Use(middle.RefererMiddleware)
	// user agent
	app.Use(middle.UserAgentMiddleware)
	// 请求限制 每秒不超过3次请求
	newLimiter := tollbooth.NewLimiter(180,
		&limiter.ExpirableOptions{
			DefaultExpirationTTL: time.Minute },)
	newLimiter.SetMessage("您的请求频率太快了!")
	app.Use(middle.LimitHandler(newLimiter))

	// index
	app.GET("/", func(ctx echo.Context) error {
		return ctx.Render(200, "index", map[string]string{
			"name": appConfig.Name,
			"ipAddr": ctx.Request().RemoteAddr,
		})
	})

	// v1 api
	v1 := app.Group("/api/v1/")
	// 网站设置
	v1.GET("base/", func(ctx echo.Context) error {
		return ctx.JSON(200, map[string]string{
			"name": appConfig.Name,
			"email": appConfig.Email,
			"api": appConfig.Api,
			"apiVersion": appConfig.ApiVersion,
		})
	})
	// 随机一条
	v1.GET("random/", controls.RandomSentence)
	// 添加 句子
	v1.POST("sentence/", controls.AddSentence)
	// 添加 订阅
	v1.POST("subscribe/", controls.AddSubscribe)
	// 添加 复制数
	v1.POST("copy/", controls.AddCopyCounts)
	// webhook
	v1.POST("webhook/gitee/", controls.WebhookGitee)

	// 文章
	v1.GET("articles/", controls.FindAllArticles)
	v1.GET("article/", controls.FindArticle)

	// 友人帐
	v1.GET("links/", controls.FindAllLink)
	v1.POST("link/", controls.AddLink)

	// 反馈
	v1.POST("feedback/", controls.AddFeedBack)

	// 快传 文件
	v1.GET("transfer/", controls.GetTransferFile)
	v1.POST("transfer/", controls.TransferFile)

	// 下载快传文件
	v1.GET("download/", controls.DownloadFile)

	// 一封信
	v1.POST("letter/", controls.AddLetter)

	// 登录
	v1.POST("login/", controls.UserLogin)

	// 后台
	v1Admin := v1.Group("admin/")

	// 后台 自定义中间件
	v1Admin.Use(middle.AdminServerMiddleware)

	// 句子
	v1Admin.GET("sentences/", controls.AdminFindAllSentence) // all
	v1Admin.POST("sentence/", controls.AdminAddSentence) // add
	v1Admin.PUT("sentence/", controls.AdminChangeSentence) // change
	v1Admin.DELETE("sentence/", controls.AdminDeleteSentence) // delete

	// 订阅
	v1Admin.GET("subscribes/", controls.AdminFindAllSubscribe) // all
	v1Admin.DELETE("subscribe/", controls.AdminDeleteSubscribe)

	// 文章图片
	v1Admin.POST("articleImage/", controls.UploadArticleImage)
	v1Admin.DELETE("articleImage/", controls.RemoveArticleImage)

	// 文章
	v1Admin.GET("articles/", controls.AdminFindAllArticle) // all
	v1Admin.GET("article/", controls.AdminFindArticle) // all
	v1Admin.POST("article/", controls.AdminAddArticle) // add
	v1Admin.PUT("article/", controls.AdminChangeArticle) // add
	v1Admin.DELETE("article/", controls.AdminDeleteArticle) // delete

	// setting
	v1Admin.GET("settings/", controls.AdminSettings)
	v1Admin.PUT("settings/", controls.AdminChangeSettings)

	// 友人帐
	v1Admin.GET("links/", controls.AdminFindAllLink)
	v1Admin.POST("link/", controls.AdminAddLink)
	v1Admin.PUT("link/", controls.AdminChangeLink)
	v1Admin.DELETE("link/", controls.AdminDeleteLink)

	// 反馈
	v1Admin.GET("feedbacks/", controls.AdminFindAllFeedBack)
	v1Admin.POST("feedback/", controls.AdminAddFeedBack)
	v1Admin.PUT("feedback/", controls.AdminChangeFeedBack)
	v1Admin.DELETE("feedback/", controls.AdminDeleteFeedBack)

	// 快传
	v1Admin.GET("transfers/", controls.AdminFindAllTransferFile)
	v1Admin.POST("transfer/", controls.AdminAddTransferFile)
	v1Admin.PUT("transfer/", controls.AdminChangeTransferFile)
	v1Admin.DELETE("transfer/", controls.AdminDeleteTransferFile)

	// 信件
	v1Admin.GET("letters/", controls.AdminFindAllLetter)
	v1Admin.GET("letter/", controls.AdminFindLetter)
	v1Admin.POST("letter/", controls.AdminAddLetter)
	v1Admin.PUT("letter/", controls.AdminChangeLetter)
	v1Admin.DELETE("letter/", controls.AdminDeleteLetter)

	// start
	app.Logger.Fatal(app.Start(Addr))
}
